package com.dp.appi.util;

import java.math.BigDecimal;

/**
 * Created by Administrator on 2016/5/16.
 */
public class PointUtil {
    private static double EARTH_RADIUS = (6378137+6356752.3142)/2;
    private static double rad(double d)
    {
        return d * Math.PI / 180.0;
    }

    public static double GetDistance(BigDecimal lng1, BigDecimal lat1, BigDecimal lng2, BigDecimal lat2)
    {
        BigDecimal radLat1 = new BigDecimal(rad(lat1.doubleValue()));
        BigDecimal radLat2 = new BigDecimal(rad(lat2.doubleValue()));
        System.out.println(radLat2);
        BigDecimal a = radLat1.subtract(radLat2);

        BigDecimal b = new  BigDecimal(rad(lng1.doubleValue())).subtract(new BigDecimal(rad(lng2.doubleValue())));
        double s = 2 * Math.sin(Math.sqrt(Math.pow(Math.sin((a.divide(new BigDecimal(2)) ).doubleValue()), 2) +
                Math.cos(radLat1.doubleValue()) * Math.cos(radLat2.doubleValue()) * Math.pow(Math.sin(a.divide(new BigDecimal(2)).doubleValue()), 2)));
        s = s * EARTH_RADIUS;
        return s;
    }

//    static double M_PI = Math.PI;
//    public static double[] lonLat2Mercator(double lon,double lat)
//    {
//        double[] xy = new double[2];
//        double x = lon *20037508.342789/180;
//        double y = Math.log(Math.tan((90+lat)*M_PI/360))/(M_PI/180);
//        y = y *20037508.34789/180;
//        xy[0] = x;
//        xy[1] = y;
//        return xy;
//    }


    static double DEF_PI = 3.14159265359; // PI
    static double DEF_2PI= 6.28318530712; // 2*PI
    static double DEF_PI180= 0.01745329252; // PI/180.0
    static double DEF_R =6370693.5; // radius of earth
    //适用于近距离
    public static double GetShortDistance(double lon1, double lat1, double lon2, double lat2)
    {
        double ew1, ns1, ew2, ns2;
        double dx, dy, dew;
        double distance;
        // 角度转换为弧度
        ew1 = lon1 * DEF_PI180;
        ns1 = lat1 * DEF_PI180;
        ew2 = lon2 * DEF_PI180;
        ns2 = lat2 * DEF_PI180;
        // 经度差
        dew = ew1 - ew2;
        // 若跨东经和西经180 度，进行调整
        if (dew > DEF_PI)
            dew = DEF_2PI - dew;
        else if (dew < -DEF_PI)
            dew = DEF_2PI + dew;
        dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
        dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
        // 勾股定理求斜边长
        distance = Math.sqrt(dx * dx + dy * dy);
        return distance;
    }
    //适用于远距离
    public static double GetLongDistance(double lon1, double lat1, double lon2, double lat2)
    {
        double ew1, ns1, ew2, ns2;
        double distance;
        // 角度转换为弧度
        ew1 = lon1 * DEF_PI180;
        ns1 = lat1 * DEF_PI180;
        ew2 = lon2 * DEF_PI180;
        ns2 = lat2 * DEF_PI180;
        // 求大圆劣弧与球心所夹的角(弧度)
        distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2);
        // 调整到[-1..1]范围内，避免溢出
        if (distance > 1.0)
            distance = 1.0;
        else if (distance < -1.0)
            distance = -1.0;
        // 求大圆劣弧长度
        distance = DEF_R * Math.acos(distance);
        return distance;
    }
    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {
       System.out.println(GetLongDistance(106.486654, 29.490295, 106.581515, 29.615467));
       System.out.println(GetShortDistance(106.486654, 29.490295, 106.581515, 29.615467));
    }

}
